package com.gitee.wsl.common.chart.render.foreground.info

import android.graphics.*
import com.gitee.wsl.common.chart.ChartEnum
import com.gitee.wsl.common.chart.model.PlotDot
import com.gitee.wsl.common.chart.render.shape.plot.PlotDotRender.Companion.plotDotRender
import com.gitee.wsl.common.ui.draw.type.DotStyle
import com.gitee.wsl.android.ui.ext.type.drawMultilineText
import com.gitee.wsl.android.ui.ext.type.textHeight
import com.gitee.wsl.android.ui.ext.type.textWidth

import timber.log.Timber

open class Info {

     val borderPaint: Paint by lazy {
         Paint(Paint.ANTI_ALIAS_FLAG).apply { style = Paint.Style.STROKE }
     }
    
     val backgroundPaint: Paint by lazy {
         Paint(Paint.ANTI_ALIAS_FLAG).apply {
             alpha = 100
             color = Color.YELLOW
         }
     }

     val rect = RectF()
     val rowSpan = 5.0f
     val colSpan = 10.0f
     val margin = 5f

     var style = ChartEnum.DyInfoStyle.ROUNDRECT //0 rect, 1 roundRect


     var roundRectX = 5f
     var roundRectY = 5f

     var clickedDotStyleList = mutableListOf<PlotDot>()
     var clickedTextList = mutableListOf<String>()
     var clickedPaintList = mutableListOf<Paint>()
     var centerXY: PointF? = null

     var positionAlign = Paint.Align.RIGHT
     var rectWidth = 0.0f
     var rectHeight = 0.0f

    //带箭头的框中，箭头的高度
    var scale = 0.2f
    
    //圆框半径
    var radius = 0f

    var showBoxBorder = true
    var showBackground = true
    
    val validateParams: Boolean
       get() {
           if (null == centerXY) {
               Timber.d( "没有传入点击坐标.")
               return false
           }
           if ( clickedPaintList.isEmpty()) {
               Timber.d("没有传入画笔.")
               return false
           }
           return true
       }

    private fun getContentRect() {
        val countDots = clickedDotStyleList.size
        val countPaint = clickedPaintList.size
        val countText = clickedPaintList.size
        //if(0 == countText && 0 == countDots ) return;
        var textWidth = 0.0f
        var textHeight = 0.0f
        var maxWidth = 0.0f
        var maxHeight = 0.0f
        var rowWidth = 0.0f
        var paint: Paint? = null
        var text = ""
        for (i in 0 until countText) {
            if (countPaint > i) paint = clickedPaintList[i]
            if (null == paint) break
            text = clickedTextList[i]
            textHeight =paint.textHeight
            textWidth =paint.textWidth(text)
            rowWidth = textWidth
            if (countDots > i) {
                val plot = clickedDotStyleList[i]
                if (plot.dotStyle != DotStyle.HIDE) {
                    rowWidth += textHeight + colSpan
                }
            }
            if (rowWidth.compareTo(maxWidth) == 1) {
                maxWidth = rowWidth
            }
            maxHeight += textHeight
        }
        //paint.reset();
        maxHeight += 2 * margin + countText * rowSpan
        maxWidth += 2 * margin
        rectWidth = maxWidth
        rectHeight = maxHeight
        getInfoRect()
    }

    private fun getInfoRect() {
        when (positionAlign) {
            Paint.Align.LEFT -> {
                rect.left = centerXY!!.x - rectWidth
                rect.right = centerXY!!.x
                rect.top = centerXY!!.y - rectHeight
                rect.bottom = centerXY!!.y
            }
            Paint.Align.CENTER -> {
                val halfWidth = rectWidth / 2
                rect.left = centerXY!!.x - halfWidth
                rect.right = centerXY!!.x + halfWidth
                rect.top = centerXY!!.y - rectHeight
                rect.bottom = centerXY!!.y
            }
            Paint.Align.RIGHT -> {
                rect.left = centerXY!!.x
                rect.right = centerXY!!.x + rectWidth
                rect.top = centerXY!!.y - rectHeight
                rect.bottom = centerXY!!.y
            }
            else -> {}
        }
    }


    protected fun setCenterXY(x: Float, y: Float) {
        if (null == centerXY) centerXY = PointF()
        centerXY!!.x = x
        centerXY!!.y = y
    }

    protected fun addInfo(text: String, paint: Paint) {
        val dot = PlotDot()
        dot.dotStyle = DotStyle.HIDE
        addInfo(dot, text, paint)
    }

    protected fun addInfo(dotStyle: PlotDot, text: String, paint: Paint) {
        clickedDotStyleList.add(dotStyle)
        clickedTextList.add(text)
        clickedPaintList.add(paint)
    }

    protected fun drawInfo(canvas: Canvas) //hint  ToolTips
    {
        if (!validateParams) return
        val countDots = clickedDotStyleList.size
        val countPaint =clickedPaintList.size
        val countText =  clickedPaintList.size
        if (0 == countText && 0 == countDots) return
        getContentRect()
        
        if (ChartEnum.DyInfoStyle.RECT == style) {
            if (showBackground) canvas.drawRect(rect, backgroundPaint)
            if (showBoxBorder) canvas.drawRect(rect,borderPaint)
        } else if (ChartEnum.DyInfoStyle.CAPRECT == style) {
            drawCapRect(canvas, rect)
        } else if (ChartEnum.DyInfoStyle.CAPROUNDRECT == style) {
            drawCapRound(canvas, rect)
        } else if (ChartEnum.DyInfoStyle.CIRCLE == style) {
            drawCircle(canvas, rect)
            //}else if(ChartEnum.DyInfoStyle.ELLIPSE == mStyle){						
        } else {
            if (showBackground) canvas.drawRoundRect(
                rect,
                roundRectX,
                roundRectY,
                backgroundPaint
            )
            if (showBoxBorder) canvas.drawRoundRect(
                rect,
                roundRectX,
                roundRectY,
               borderPaint
            )
        }
        val currDotsX = rect.left + margin
        var currRowY = rect.top + margin
        var textHeight = 0.0f
        var currTextX = currDotsX
        var j = 0
        for (i in 0 until countText) {
            if (countPaint > i) j = i
            //if (null == mClickedPaint[j]) break
            textHeight =clickedPaintList[j].textHeight
            if (countDots > i) {
                val plot = clickedDotStyleList[i]
                if (plot.dotStyle != DotStyle.HIDE) //画dot
                {
                    plotDotRender.renderDot(
                        canvas, plot,
                        currDotsX + textHeight / 2,
                        currRowY + textHeight / 2,
                        clickedPaintList[j]
                    )
                    currTextX = currDotsX + textHeight + colSpan
                }
            }
            if (countText > i)
                canvas.drawMultilineText(
                clickedPaintList[j],
                clickedTextList[i],
                currTextX, currRowY + textHeight
            )
            currRowY += textHeight + rowSpan
            currTextX = currDotsX
        }
    }
    
    
    private fun drawCircle(canvas: Canvas, rect: RectF) {
        var radius = rect.width().coerceAtLeast(rect.height()) / 2 + 5
        if (this.radius.compareTo(0.0f) != 0) radius = this.radius
        if (showBackground) canvas.drawCircle(
            rect.centerX(),
            rect.centerY(),
            radius,
            backgroundPaint
        )
        if (showBoxBorder) canvas.drawCircle(
            rect.centerX(),
            rect.centerY(),
            radius,
            borderPaint
        )
    }

    private fun drawCapRect(canvas: Canvas, rect: RectF) {
        if (!showBackground && !showBoxBorder) return
        val AngleH = rect.width() * scale //0.2f ;
        rect.top -= AngleH
        rect.bottom -= AngleH
        val centerX = rect.left + rect.width() * 0.5f
        val AngleY = rect.bottom
        val path = Path()
        path.moveTo(rect.left, rect.bottom)
        path.lineTo(rect.left, rect.top)
        path.lineTo(rect.right, rect.top)
        path.lineTo(rect.right, rect.bottom)
        path.lineTo(centerX + AngleH, AngleY)
        path.lineTo(centerX, AngleY + AngleH)
        path.lineTo(centerX - AngleH, AngleY)
        path.close()
        if (showBackground) canvas.drawPath(path, backgroundPaint)
        if (showBoxBorder) canvas.drawPath(path,borderPaint)
    }

    private fun drawCapRound(canvas: Canvas, rect: RectF) {

        //if( !mShowBackground && !mShowBoxBorder)return;		
        if (!showBackground) return  //此风格无边框
        val AngleH = rect.width() * scale //0.2f ;
        rect.top -= AngleH
        rect.bottom -= AngleH
        val centerX = rect.left + rect.width() * 0.5f
        val angleY = rect.bottom
        val fh = backgroundPaint.textHeight
        val path = Path()
        path.moveTo(centerX + AngleH, angleY - fh)
        path.lineTo(centerX, angleY + AngleH)
        path.lineTo(centerX - AngleH, angleY - fh)
        path.close()
        canvas.drawRoundRect(this.rect, roundRectX, roundRectY, backgroundPaint)
        canvas.drawPath(path, backgroundPaint)
        path.reset()
    }
    
    protected fun clear() {
        clickedDotStyleList.clear()
        clickedTextList.clear()
        clickedPaintList.clear()
    }
    
}